package one.stand.facade;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import one.stand.advice.ResultEnum;
import one.stand.code.RedisCode;
import one.stand.dto.UserDto;
import one.stand.enums.LoginEnum;
import one.stand.event.CompanyLicenseAgreeEvent;
import one.stand.event.CompanyLicenseRefuseEvent;
import one.stand.mapper.CustomerMapper;
import one.stand.mapper.UserTaskMapper;
import one.stand.model.*;
import one.stand.service.*;
import one.stand.service.user.MenuService;
import one.stand.service.user.TokenService;
import one.stand.service.user.UserAdminService;
import one.stand.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author cjr
 */
@Service
@Slf4j
public class CompanyCardFacadeServiceImpl implements CompanyCardFacadeService {
    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private UserAdminService userAdminService;
    @Autowired
    private BusinessCardBaseService businessCardBaseService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private MessageMsgService messageMsgService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private BusinessCardService businessCardService;
    @Autowired
    private one.stand.service.CompanyService companyService;
    @Autowired
    private CompanyServiceService companyServiceService;
    @Autowired
    private CompanyLicenseService companyLicenseService;
    @Autowired
    private GoodsBaseService goodsBaseService;
    @Autowired
    private UserTaskMapper userTaskMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transfer(Integer userId, Integer companyId) {
        UserDto userModel = userAdminService.get(userId);
        AssertUtil.isFalse(userModel.isEmptyUser(), "移交用户不存在");
        AssertUtil.isFalse(userModel.isBoss(), "该用户下存在企业");

        BusinessCard businessCardModel = businessCardService.getByUserId(userId);
        AssertUtil.isFalse(null != businessCardModel, "该用户存下存在名片");

        Company companyModel = companyService.get(companyId);
        AssertUtil.isFalse(null == companyModel, "企业不存在，请退出重新登录");

        int delCard = businessCardService.removeByCompanyId(companyId);
        log.info("删除企业下所有名片：删除数量{}", delCard);

        companyServiceService.clear(companyId);

        // TODO: 2020/1/11 该功能实现有问题，只清除了企业相关数据，未发现资料被转移相关代码
//        ResultModel resultModel = userTaskService.batchDelToken(companyId);
//        log.info("删除企业所有缓存信息：", resultModel.toString());
        AssertUtil.fail("todo");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void quitCompany(Integer cardId, Integer myCardId) {
        BusinessCard businessCard = businessCardService.get(cardId);
        AssertUtil.isTrue(Objects.nonNull(businessCard) && businessCard.getIsDel() == 0, ResultEnum.PARAM_CHECK);

        BusinessCard optCard = businessCardService.get(myCardId);
        AssertUtil.isTrue(Objects.nonNull(optCard) && optCard.getIsDel() == 0
                && businessCard.getCompanyId().equals(optCard.getCompanyId()), ResultEnum.PARAM_CHECK);

        Company company = companyService.get(businessCard.getCompanyId());
        AssertUtil.isFalse(company.getUserId().equals(businessCard.getUserId()), ResultEnum.PARAM_CHECK, "BOSS不能移除哦~!");

        CustomerModel model = new CustomerModel();
        model.setAscriptionId(Long.valueOf(cardId));
        model.setIsDel(0);
        model.setCustomerState(1);
        List<CustomerModel> list = customerMapper.getCustomer(model);
        AssertUtil.isNull(list, "该员工下有独立客户，无法移除~!");

        businessCardService.remove(cardId);

        companyServiceService.sub(businessCard.getCompanyId());

        // 删除用户月目标数据
        userTaskMapper.delUserTask(new UserTaskModel() {{
            setCardId(cardId);
        }});

        // 删除缓存
        batchDelToken(Lists.newArrayList(businessCard.getUserId()));
    }

    @Override
    @Transactional
    public void dissolution(Integer companyId) {
        log.info("解散企业：{}", companyId);

        RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        AssertUtil.nonNull(optUser, "请登录");
        AssertUtil.isTrue(optUser.getCompanyId().equals(companyId), "不能解散本企业");

        Company company = companyService.get(companyId);
        AssertUtil.nonNull(company, "企业不存在");
        AssertUtil.isTrue(company.getUserId().equals(optUser.getUserId()), "没有权限，不能解散本企业");

        // 查询公司名片信息
        List<BusinessCard> businessCardModelList = businessCardBaseService.getByCompanyId(companyId);

        // 删除名片表
        businessCardService.removeByCompanyId(companyId);
        // 删除公司
        companyService.remove(companyId);

        // 修改用户role信息
        userAdminService.updateUserRoleId(company.getUserId(), 0);
        menuService.remove(company.getUserId());

        goodsBaseService.deleteByCompanyId(companyId);

        // 删除用户月目标数据
        userTaskMapper.delUserTask(new UserTaskModel() {{
            setCompanyId(companyId);
        }});
        // 删除缓存
        batchDelTokenByCard(businessCardModelList);
    }

    @Override
    @Transactional
    public void companyAudit(Integer licenseId) {
        CompanyLicense companyLicense = companyLicenseService.get(licenseId);
        Company company = companyService.get(companyLicense.getCompanyId());

        companyLicenseService.audit(licenseId);

        if (company.getIsDel() != 0) {
            return;
        }

        // init menu
        menuService.initCrm(company.getUserId(), true);
        // 清除登录状态
        tokenService.remove(Lists.newArrayList(Long.valueOf(company.getUserId())));

        applicationContext.publishEvent(new CompanyLicenseAgreeEvent(company.getCompanyId()));
    }

    @Override
    @Transactional
    public void companyRefuse(Integer licenseId, String memo) {
        CompanyLicense companyLicense = companyLicenseService.get(licenseId);
        Company company = companyService.get(companyLicense.getCompanyId());
        BusinessCard card = businessCardService.getByUserId(company.getUserId());

        companyLicenseService.refuse(licenseId, memo);

        if (company.getIsDel() != 0) {
            return;
        }

        // 查询公司名片信息
        List<BusinessCard> businessCardModelList = businessCardBaseService.getByCompanyId(companyLicense.getCompanyId());
        //删除名片
        businessCardService.removeByCompanyId(companyLicense.getCompanyId());
        //删除企业
        companyService.remove(companyLicense.getCompanyId());
        //修改用户role信息
        userAdminService.updateUserRoleId(company.getUserId(), 0);
        menuService.remove(company.getUserId());
        //删除用户月目标数据
        userTaskMapper.delUserTask(new UserTaskModel() {{
            setCompanyId(companyLicense.getCompanyId());
        }});

        // 删除缓存
        batchDelTokenByCard(businessCardModelList);

        //通知
        applicationContext.publishEvent(new CompanyLicenseRefuseEvent(companyLicense.getCompanyId(), company.getCompanyName(), memo, card.getPhone()));
    }

    private void batchDelToken(Integer companyId) {
        // 查询公司名片信息
        List<BusinessCard> businessCardModelList = businessCardBaseService.getByCompanyId(companyId);

        if (OneListUtil.isNotEmpty(businessCardModelList)) {
            List<Integer> userIds = businessCardModelList.stream().map(BusinessCard::getUserId).collect(Collectors.toList());
            batchDelToken(userIds);
        }
    }

    private void batchDelTokenByCard(List<BusinessCard> businessCardModelList) {

        if (OneListUtil.isNotEmpty(businessCardModelList)) {
            List<Integer> userIds = businessCardModelList.stream().map(BusinessCard::getUserId).collect(Collectors.toList());
            batchDelToken(userIds);
        }
    }

    private void batchDelToken(List<Integer> userIds) {
        if (OneListUtil.isEmpty(userIds)) return;

        Set<String> keyList = new HashSet<>();
        List<Long> userIdsLong = Lists.newArrayListWithExpectedSize(userIds.size());
        for (Integer userId : userIds) {
            keyList.addAll(redisUtil.getKey(RedisCode.getImList(Long.valueOf(userId), LoginEnum.CRM.getCode())));
            keyList.addAll(redisUtil.getKey(RedisCode.getUserWebSocketMessageRecord(userId + "", "*", LoginEnum.CRM.getCode())));
            keyList.addAll(redisUtil.getKey(RedisCode.getUnreadMessage(userId + "", "*", LoginEnum.CRM.getCode())));
            userIdsLong.add(Long.valueOf(userId));

            messageMsgService.removeUnreadNumAll(String.valueOf(userId), LoginEnum.CRM.getCode());
        }
        log.info("公司解散需要删除得key:{}", JSON.toJSONString(keyList));
        redisUtil.batchDel(keyList);
        tokenService.remove(userIdsLong);
    }
}
